package utils

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"os"
	"server/models"
	"server/openapi"
	"time"

	"github.com/spf13/viper"
)

var (
	Application models.Application
)

// 初始化配置文件
func InitConfig() {
	workDir, _ := os.Getwd()
	viper.SetConfigName("application")
	viper.SetConfigType("yaml")
	viper.AddConfigPath(workDir + "/config")
	err := viper.ReadInConfig()
	if err != nil {
		log.Fatalf("Fatal error config file: %v", err)
	}
	// 将配置文件内容映射到 Config 结构体
	err = viper.Unmarshal(&Application)
	if err != nil {
		log.Fatalf("Failed to unmarshal config: %v", err)
	}
}

// https://davidleitw.github.io/posts/time01/
func refershTokenTaskHandler(quitChan chan struct{}) {
	ticker := time.NewTicker(90 * time.Minute)
	refreshDuToken := time.NewTicker(90 * time.Minute)
	defer ticker.Stop()
	defer refreshDuToken.Stop()
	for {
		select {
		case <-ticker.C:
			var aliPan = &models.AliPan{
				Host:         Application.Alipan.Host,
				ClientId:     Application.Alipan.ClientId,
				ClientSecret: Application.Alipan.ClientSecret,
			}
			aliPan.Path = "/oauth/access_token"
			_, err := aliPan.RefreshAuthentication()
			if err != nil {
				fmt.Println("token 刷新失败")
			} else {
				fmt.Println("token 刷新成功")
			}
		// 添加其他需要监听的通道事件
		case <-refreshDuToken.C:
			// controller.CommonRefresh()
			_, err := commonRefresh()
			if err != nil {
				fmt.Println("token du 刷新失败")
			} else {
				fmt.Println("token du 刷新成功")
			}
		case <-quitChan:
			fmt.Println("Received quit signal. Exiting...")
			return
		}
	}
}

func InitTaskHandler(quitChan chan struct{}) {
	go refershTokenTaskHandler(quitChan)
}

func commonRefresh() (map[string]interface{}, error) {
	api_client, _ := getApiClientFunc()
	workDir, _ := os.Getwd()
	var jsonMap map[string]interface{}
	refreshTokenValue, err := readTokenFromFile(workDir + "/DuPanRefresh")
	if err != nil {
		fmt.Fprintf(os.Stderr, "err: %v\n", err)
		return jsonMap, err
	}

	var duPan = &models.DuPan{
		Host:      Application.Dupan.Host,
		Path:      "/token",
		AppId:     Application.Dupan.AppId,
		AppKey:    Application.Dupan.AppKey,
		SecretKey: Application.Dupan.Secretkey,
	}

	_, r, err := api_client.AuthApi.OauthTokenRefreshToken(context.Background()).RefreshToken(refreshTokenValue).ClientId(duPan.AppKey).ClientSecret(duPan.SecretKey).Execute()
	if err != nil {
		fmt.Fprintf(os.Stderr, "err: %v\n", err)
		return jsonMap, err
	}
	bodyBytes, err := io.ReadAll(r.Body)
	if err != nil {
		fmt.Fprintf(os.Stderr, "err: %v\n", err)
		return jsonMap, err
	}

	if err := json.Unmarshal(bodyBytes, &jsonMap); err != nil {
		fmt.Fprintf(os.Stderr, "err: %v\n", err)
		return jsonMap, err
	}
	// 7200s 两个小时后刷新token
	if jsonMap["access_token"] != "" {
		// 从文件中读取token
		workDir, _ := os.Getwd()
		writeTokenToFile(jsonMap["access_token"].(string), workDir+"/DuPanConfig")
	}
	if jsonMap["refresh_token"] != "" {
		// 从文件中读取token
		workDir, _ := os.Getwd()
		writeTokenToFile(jsonMap["refresh_token"].(string), workDir+"/DuPanRefresh")
	}
	return jsonMap, err
}

func getApiClientFunc() (*openapi.APIClient, string) {
	workDir, _ := os.Getwd()
	refreshTokenValue, err := readTokenFromFile(workDir + "/DuPanConfig")
	if err != nil {
		fmt.Fprintf(os.Stderr, "err: %v\n", err)
	}
	accessToken := refreshTokenValue // string
	configuration := openapi.NewConfiguration()
	api_client := openapi.NewAPIClient(configuration)
	return api_client, accessToken
}

// 读取token
func readTokenFromFile(filename string) (string, error) {
	tokenBytes, err := os.ReadFile(filename)
	if err != nil {
		return "", err
	}
	token := string(tokenBytes)
	return token, nil
}

// 存储token

// 将token写入文件
func writeTokenToFile(token, filename string) error {
	// 打开文件
	file, err := os.Create(filename)
	if err != nil {
		return fmt.Errorf("failed to create file: %v", err)
	}
	defer file.Close()
	// 写入token
	_, err = file.WriteString(token)
	if err != nil {
		return fmt.Errorf("failed to write to file: %v", err)
	}
	return nil
}
